package com.juliasoft.beedeedee.factories;
import java.nio.ByteBuffer;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
public class IntegrityCheckUniqueTable extends ResizingAndGarbageCollectedUniqueTable {
protected static final int CHECKSUM_OFFSET = 5;
protected static final int NODE_SIZE = 6;
IntegrityCheckUniqueTable(int size, int cacheSize, Factory factory) {
super(size, cacheSize, factory);
// TODO Auto-generated constructor stub
}
@Override
public int getNodeSize() {
return NODE_SIZE;
}
private void checkNodeIntegrity(int id) {
int value = nodeChecksum(id);
if (value != ut[id * getNodeSize() + CHECKSUM_OFFSET]) {
throw new CorruptedNodeException(id);
}
}
private int nodeChecksum(int id) {
ByteBuffer byteBuffer = ByteBuffer.allocate((getNodeSize() - 1) * 4);
byteBuffer.putInt(ut[id * getNodeSize() + VAR_OFFSET]);
byteBuffer.putInt(ut[id * getNodeSize() + LOW_OFFSET]);
byteBuffer.putInt(ut[id * getNodeSize() + HIGH_OFFSET]);
byteBuffer.putInt(ut[id * getNodeSize() + NEXT_OFFSET]);
byteBuffer.putInt(ut[id * getNodeSize() + HASHCODEAUX_OFFSET]);
byte[] byteArray = byteBuffer.array();
Checksum checksum = new CRC32();
checksum.update(byteArray, 0, byteArray.length);
return (int) checksum.getValue();
}
/*
* Reading
*/
@Override
public int var(int id) {
checkNodeIntegrity(id);
return super.var(id);
}
@Override
public int low(int id) {
checkNodeIntegrity(id);
return super.low(id);
}
@Override
public int high(int id) {
checkNodeIntegrity(id);
return super.high(id);
}
@Override
protected int next(int id) {
checkNodeIntegrity(id);
return super.next(id);
}
@Override
protected int hashCodeAux(int id) {
checkNodeIntegrity(id);
return super.hashCodeAux(id);
}
@Override
protected boolean isVarLowHigh(int id, int var, int low, int high) {
checkNodeIntegrity(id);
return super.isVarLowHigh(id, var, low, high);
}
/*
* Writing
*/
@Override
protected void setAt(int where, int varNumber, int lowNode, int highNode) {
super.setAt(where, varNumber, lowNode, highNode);
ut[where * getNodeSize() + CHECKSUM_OFFSET] = nodeChecksum(where);
}
@Override
protected void setNext(int node, int nextNode) {
super.setNext(node, nextNode);
ut[node * getNodeSize() + CHECKSUM_OFFSET] = nodeChecksum(node);
}
@Override
protected void setVarLowHighHash(int node, int varNumber, int lowNode, int highNode, int hca) {
super.setVarLowHighHash(node, varNumber, lowNode, highNode, hca);
ut[node * getNodeSize() + CHECKSUM_OFFSET] = nodeChecksum(node);
}
}